package utils

// 微信小程序 发送订阅消息， 不使用第三方库

import (
	"os"
	// "strconv"
	"io"
	"time"
	"encoding/json"
	"bytes"
	"net/http"
    "net/url"


	"fmt"
    // "github.com/ArtisanCloud/PowerWeChat/v3/src/miniProgram"
)


// TokenResponse 接收返回的参数 
type TokenResponse struct {
    AccessToken string `json:"access_token"`
    ExpiresIn   int    `json:"expires_in"`
    CurrentTime int64  `json:"current_time"` // 这个是逻辑需要，可以不加
}

func FetchAccessToken() (TokenResponse, error) {

	var res TokenResponse

	url := "https://api.weixin.qq.com/cgi-bin/token"
	client := &http.Client{}
	params := map[string]string {
		"grant_type": "client_credential",
		"appid":      os.Getenv("MINIPROGRAM_APP_ID"),
		"secret":     os.Getenv("MINIPROGRAM_SECRET"),
	}

	req, err := http.NewRequest("GET", url, nil)

	q := req.URL.Query()
	for key, value := range params {
		q.Add(key, value)
	}
	req.URL.RawQuery = q.Encode()

	resp, err := client.Do(req)
	if err != nil {
		return res, err
	}

	defer func(Body io.ReadCloser) {
		Body.Close()
		// err := Body.Close()
		// if err != nil {
		// 	return "", err
		// }
	}(resp.Body)

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return res, err
	}

	err = json.Unmarshal(body, &res)


	if err != nil {
		return res, err
	}

	res.CurrentTime = time.Now().Unix()

	return res, nil
}

// 新增数据结构定义
type DataItem struct {
    Value string `json:"value"`
}

// 订阅消息请求参数
type SubscribeMessageRequest struct {
	ToUser     string                    `json:"touser"`
	TemplateID string                    `json:"template_id"`
	Page       string                    `json:"page,omitempty"`
    Data map[string]DataItem 				`json:"data"`
	MiniprogramState       string        `json:"miniprogram_state"`
	Lang       string                    `json:"lang"`
	
}

// 微信接口响应基础结构
type WeChatResponse struct {
	Errcode int    `json:"errcode"`
	Errmsg  string `json:"errmsg"`
}

// 发送订阅消息
func SendSubscribeMessage(
	accessToken string,
	openID string,
	templateID string,
	page string,
	data map[string]string,
) error {
	// 参数校验
	if openID == "" || templateID == "" {
		return fmt.Errorf("openID 和 templateID 不能为空")
	}

	// 构建消息数据
	messageData := make(map[string]DataItem)
	for k, v := range data {
		messageData[k] = DataItem{Value: v}
	}

	// 构造请求体
	requestBody := SubscribeMessageRequest{
		ToUser:     openID,
		TemplateID: templateID,
		Page:       page,
		Data:       messageData,
		MiniprogramState: "trial", //体验版
		Lang: "zh_CN",
	}

	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return fmt.Errorf("JSON序列化失败: %w", err)
	}

	fmt.Printf("jsonData: %#v", string(jsonData))

	// 发送请求
	url := fmt.Sprintf(
		"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s",
		accessToken,
	)
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return fmt.Errorf("发送请求失败: %w", err)
	}
	defer resp.Body.Close()

	// 处理响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应内容失败: %w", err)
	}

	var result WeChatResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return fmt.Errorf("解析响应JSON失败: %w", err)
	}

	if result.Errcode != 0 {
		return fmt.Errorf("微信接口错误[%d]: %s", result.Errcode, result.Errmsg)
	}

	return nil
}


// SessionData 用于解析返回数据
type MnpLoginSessionData struct {
    OpenID    string `json:"openid"`
    SessionKey string `json:"session_key"`
    UnionID   string `json:"unionid"`
    ErrCode   int    `json:"errcode"`
    ErrMsg    string `json:"errmsg"`
}

func MnpLoginSessionInfo(jsCode string) (MnpLoginSessionData, error) {
    // 构建请求URL
    params := url.Values{}
    params.Add("appid", os.Getenv("MINIPROGRAM_APP_ID"))
    params.Add("secret", os.Getenv("MINIPROGRAM_SECRET"))
    params.Add("js_code", jsCode)
    params.Add("grant_type", "authorization_code")
    urlStr := "https://api.weixin.qq.com/sns/jscode2session?" + params.Encode()

    // 发起GET请求
    resp, err := http.Get(urlStr)
    if err != nil {
        return MnpLoginSessionData{}, err
    }
    defer resp.Body.Close()

    // 读取响应体
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return MnpLoginSessionData{}, err
    }

    // 解析响应数据
    var session MnpLoginSessionData
    err = json.Unmarshal(body, &session)
    if err != nil {
        return MnpLoginSessionData{}, err
    }

    return session, nil
}